﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;

namespace cubo
{
    class Nave : Controllable
    {
        private Vector3 posicaoNave;
        private int combustivel;
        private int combustivelMax;
        private float velocidade, velocidadePropulsao, aceleracaoPropulsao, aceleracaoQueda, aceleracao;
        private Model modelo;
        private String logTeclado;
        private float rotacaoX;
        private float rotacaoZ;

        public Nave(Vector3 shipPosition, Model modelo)
        {
            this.posicaoNave = shipPosition;
            this.modelo = modelo;
            this.combustivel = 10000;  //Integrar ao HUD e ver se é suficiente yada yada yada
            this.combustivelMax = 10000;    //Integrar ao HUD e ver se é suficiente yada yada yada
            this.velocidade = 0.1f;
            this.velocidadePropulsao = 0.2f;
            this.aceleracaoPropulsao = 0.0f;
            this.aceleracao = 0.0f;
            this.aceleracaoQueda = 0.0f;
            this.logTeclado = "";
            this.rotacaoZ = 0.0f;
            this.rotacaoX = 0.0f;

        }        

        public void setPosicao(Vector3 posicao)
        {
            this.posicaoNave = posicao;
        }

        public Vector3 getPosicao() 
        {
            return this.posicaoNave;
        }

        public void setCombustivel(int combustivel)
        {
            this.combustivel = combustivel;
        }

        public int getCombustivel()
        {
            return this.combustivel;
        }

        public int getCombustivelMax() 
        {
            return this.combustivelMax;
        }

        public void setCombustivelMax(int combustivelMax)
        {
            this.combustivelMax = combustivelMax;
        }


        public void Draw(BasicEffect efeitoBasico, GraphicsDevice graphicsDevice)
        {
            //desenhaNave(this.modelo, efeitoBasico, graphicsDevice);

            //efetua a rotação da nave
            //efeitoBasico.World *= Matrix.CreateRotationZ(MathHelper.ToRadians(rotacaoY)) * Matrix.CreateRotationZ(MathHelper.ToRadians(rotacaoZ));

            efeitoBasico.World *= Matrix.CreateTranslation(- this.posicaoNave.X ,  - 2.0f - this.posicaoNave.Y , - this.posicaoNave.Z ) *
                Matrix.CreateRotationZ(MathHelper.ToRadians(rotacaoZ)) *
                Matrix.CreateTranslation(this.posicaoNave.X , 2.0f + this.posicaoNave.Y , this.posicaoNave.Z );

            efeitoBasico.World *= Matrix.CreateTranslation( - this.posicaoNave.X, -2.0f - this.posicaoNave.Y, - this.posicaoNave.Z) *
                 Matrix.CreateRotationX(MathHelper.ToRadians(rotacaoX)) *
                Matrix.CreateTranslation(this.posicaoNave.X, 2.0f + this.posicaoNave.Y, this.posicaoNave.Z);    

                //translation(-x, -y,-z) * rotate(alfa) * translation(x,y,z)
            
            modelo.Draw(efeitoBasico.World, efeitoBasico.View, efeitoBasico.Projection);

            
        }

        public void Update(GameTime gameTime, KeyboardState estadoTeclado)
        {
            if (!(posicaoNave.Y <= 0))
            {
                //Botão direcional para cima pressionado
                if (getKeyDownUP(estadoTeclado))
                {
                    rotacaoX -= 0.5f;
                }
                else if (getKeyDownDOWN(estadoTeclado)) //Botão direcional para baixo pressionado
                {
                    rotacaoX += 0.5f;
                }

                //Botão direcional para direita pressionado
                if (getKeyDownRIGHT(estadoTeclado))
                {
                    rotacaoZ -= 0.5f;
                }
                else if (getKeyDownLEFT(estadoTeclado)) //Botão direcional para esquerda pressionado
                {
                    rotacaoZ += 0.5f;
                }

				//Botão W pressionado
                if (getKeyDownW(estadoTeclado))
                {
                    this.logTeclado = "W"; //Define o ultimo botão apertado
                    if (this.aceleracao < this.velocidade)
                    {
                        this.aceleracao += 0.001f;
                    }
                    this.posicaoNave.Z -= this.aceleracao;
                }

                //Botão S pressionado
                if (getKeyDownS(estadoTeclado))
                {
                    this.logTeclado = "S"; //Define o ultimo botão apertado
                    if (this.aceleracao < this.velocidade)
                    {
                        this.aceleracao += 0.001f;
                    }
                    this.posicaoNave.Z += this.aceleracao;
                }

                //Botão A pressionado
                if (getKeyDownA(estadoTeclado))
                {
                    this.logTeclado = "A"; //Define o ultimo botão apertado
                    if (this.aceleracao < this.velocidade)
                    {
                        this.aceleracao += 0.001f;
                    }
                    this.posicaoNave.X -= this.aceleracao;
                }

                //Botão D pressionado
                if (getKeyDownD(estadoTeclado))
                {
                    this.logTeclado = "D"; //Define o ultimo botão apertado
                    if (this.aceleracao < this.velocidade)
                    {
                        this.aceleracao += 0.001f;
                    }
                    this.posicaoNave.X += this.aceleracao;
                }

                //Nenhum botão pressionado
                if (!getKeyDownW(estadoTeclado) && !getKeyDownS(estadoTeclado) && !getKeyDownA(estadoTeclado) && !getKeyDownD(estadoTeclado))
                {
                    if (this.aceleracao > 0)
                    {
                        this.aceleracao -= 0.001f;
                    }

                    //Verifica qual foi o ultimo botão pressionado
                    if (this.logTeclado == "W")
                    {
                        this.posicaoNave.Z -= this.aceleracao;
                    }
                    if (this.logTeclado == "S")
                    {
                        this.posicaoNave.Z += this.aceleracao;
                    }
                    if (this.logTeclado == "A")
                    {
                        this.posicaoNave.X -= this.aceleracao;
                    }
                    if (this.logTeclado == "D")
                    {
                        this.posicaoNave.X += this.aceleracao;
                    }
                }                    
            }

            //Barra de espaço pressionada
            if (getKeyDownBarraEspaco(estadoTeclado) && this.combustivel > 0)
            {
                this.aceleracaoQueda = 0.0f;

                if (this.aceleracaoPropulsao < this.velocidadePropulsao)
                {
                    this.aceleracaoPropulsao += 0.001f;
                }
                
                //Ver essa parada aqui
                this.posicaoNave.X += (float) (this.aceleracaoPropulsao * (1 - Math.Cos(- rotacaoZ)) /** Math.Cos(rotacaoX)*/);
                this.posicaoNave.Y += (float) (this.aceleracaoPropulsao * (1 + Math.Sin(rotacaoZ)));
                this.posicaoNave.Z -= (float) (this.aceleracaoPropulsao * (1 - Math.Cos(rotacaoZ)));
                this.combustivel -= 2;
            }

            //Barra de espaço solta
            if (getKeyUpBarraEspaco(estadoTeclado) || this.combustivel <= 0)
            {
                if (this.posicaoNave.Y > 0)
                {
                    if (this.aceleracaoPropulsao > 0)
                    {
                        this.aceleracaoPropulsao -= 0.001f;
                        this.posicaoNave.Y += this.aceleracaoPropulsao;
                    }
                    else
                    {
                        if (this.aceleracaoQueda < Mundo.gravidade)
                        {
                            this.aceleracaoQueda += 0.001f;
                        }
                        this.posicaoNave.Y -= this.aceleracaoQueda;
                    }
                }
                else
                {
                    this.aceleracao = 0.0f;
                    this.aceleracaoPropulsao = 0.0f;
                }
            }
        }

        private void desenhaNave(Model m, BasicEffect be, GraphicsDevice graphicsDevice)
        {
            foreach (ModelMesh mm in m.Meshes)
            {
                foreach (ModelMeshPart mmp in mm.MeshParts)
                {
                    graphicsDevice.SetVertexBuffer(mmp.VertexBuffer, mmp.VertexOffset);
                    graphicsDevice.Indices = mmp.IndexBuffer;
                    be.CurrentTechnique.Passes[0].Apply();
                    graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0,mmp.NumVertices, mmp.StartIndex, mmp.PrimitiveCount);
                    
                }
            }
        }


        public bool getKeyDownN(KeyboardState estadoTeclado)
        {
            if (estadoTeclado.IsKeyDown(Keys.N))
            {
                return true;
            }

            return false;
        }

        public bool getKeyDownP(KeyboardState estadoTeclado)
        {
            if (estadoTeclado.IsKeyDown(Keys.P))
            {
                return true;
            }

            return false;
        }

        public bool getKeyDownESC(KeyboardState estadoTeclado)
        {
            if (estadoTeclado.IsKeyDown(Keys.Escape))
            {
                return true;
            }

            return false;
        }

        public bool getKeyDownBarraEspaco(KeyboardState estadoTeclado)
        {
            if (estadoTeclado.IsKeyDown(Keys.Space))
            {
                return true;
            }

            return false;
        }

        public bool getKeyUpBarraEspaco(KeyboardState estadoTeclado)
        {
            if (estadoTeclado.IsKeyUp(Keys.Space))
            {
                return true;
            }

            return false;
        }

        public bool getKeyDownW(KeyboardState estadoTeclado)
        {
            if (estadoTeclado.IsKeyDown(Keys.W))
            {
                return true;
            }

            return false;
        }

        public bool getKeyUpW(KeyboardState estadoTeclado)
        {
            if (estadoTeclado.IsKeyUp(Keys.W))
            {
                return true;
            }

            return false;
        }

        public bool getKeyDownA(KeyboardState estadoTeclado)
        {
            if (estadoTeclado.IsKeyDown(Keys.A))
            {
                return true;
            }

            return false;
        }

        public bool getKeyUpA(KeyboardState estadoTeclado)
        {
            if (estadoTeclado.IsKeyUp(Keys.A))
            {
                return true;
            }

            return false;
        }

        public bool getKeyDownS(KeyboardState estadoTeclado) 
        {
            if (estadoTeclado.IsKeyDown(Keys.S))
            {
                return true;
            }

            return false;
        }

        public bool getKeyUpS(KeyboardState estadoTeclado)
        {
            if (estadoTeclado.IsKeyUp(Keys.S))
            {
                return true;
            }

            return false;
        }

        public bool getKeyDownD(KeyboardState estadoTeclado)
        {
            if (estadoTeclado.IsKeyDown(Keys.D))
            {
                return true;
            }

            return false;
        }

        public bool getKeyUpD(KeyboardState estadoTeclado)
        {
            if (estadoTeclado.IsKeyUp(Keys.D))
            {
                return true;
            }

            return false;
        }

        public bool getKeyDownUP(KeyboardState estadoTeclado) 
        {
            if (estadoTeclado.IsKeyDown(Keys.Up))
            {
                return true;
            }

            return false;
        }
        
        public bool getKeyDownDOWN(KeyboardState estadoTeclado) 
        {
            if (estadoTeclado.IsKeyDown(Keys.Down))
            {
                return true;
            }

            return false;
        }

        public bool getKeyDownLEFT(KeyboardState estadoTeclado) 
        {
            if (estadoTeclado.IsKeyDown(Keys.Left))
            {
                return true;
            }

            return false;
        }

        public bool getKeyDownRIGHT(KeyboardState estadoTeclado) 
        {
            if (estadoTeclado.IsKeyDown(Keys.Right))
            {
                return true;
            }

            return false;
        }

    }
}
